package sessions;

import java.sql.Date;
import java.util.LinkedList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import entities.FriendshipRequest;
import entities.Status;
import entities.User;
import exceptions.FriendshipRequestException;

/**
 * Session Bean implementation class FriendshipManager
 */
@Stateless
public class FriendshipManager implements FriendshipManagerRemote,
		FriendshipManagerLocal {

	@PersistenceContext(unitName = "SWIMv2")
	private EntityManager em;

	/**
	 * Default constructor.
	 */
	public FriendshipManager() {
		// TODO Auto-generated constructor stub
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.FriendshipManagerRemote#request(entities.User,
	 * entities.User, java.lang.String)
	 */
	@Override
	public void request(User fromUser, User toUser, String message)
			throws FriendshipRequestException {
		String from = fromUser.getUsername();
		String to = toUser.getUsername();
		if (!from.equals(to)) {
			List<FriendshipRequest> result = new LinkedList<FriendshipRequest>();
			Query q = em
					.createQuery("FROM FriendshipRequest fr WHERE (fr.fromUser=:fromUser AND fr.toUser=:toUser) OR (fr.fromUser=:toUser AND fr.toUser=:fromUser)");
			q.setParameter("fromUser", fromUser);
			q.setParameter("toUser", toUser);
			List<?> res = q.getResultList();
			for (Object obj : res) {
				result.add((FriendshipRequest) obj);
			}
			if (result.isEmpty()) {
				FriendshipRequest fr = new FriendshipRequest();
				fr.setFrom(fromUser);
				fr.setTo(toUser);
				fr.setMessage(message);
				fr.setDate(new Date(System.currentTimeMillis()));
				fr.setStatus(Status.PENDING);
				em.persist(fr);
				// em.flush();
				return;
			}
		}
		throw new FriendshipRequestException();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.FriendshipManagerRemote#fetchIncoming(entities.User)
	 */
	@Override
	public List<FriendshipRequest> fetchIncoming(String username) {
		List<FriendshipRequest> result = new LinkedList<FriendshipRequest>();
		Query q = em
				.createQuery("FROM FriendshipRequest fr WHERE fr.toUser.username=:username");
		q.setParameter("username", username);
		List<?> res = q.getResultList();
		for (Object obj : res) {
			result.add((FriendshipRequest) obj);
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.FriendshipManagerRemote#fetchOutgoing(entities.User)
	 */
	@Override
	public List<FriendshipRequest> fetchOutgoing(String username) {
		List<FriendshipRequest> result = new LinkedList<FriendshipRequest>();
		Query q = em
				.createQuery("FROM FriendshipRequest fr WHERE fr.fromUser.username=:username");
		q.setParameter("username", username);
		List<?> res = q.getResultList();
		for (Object obj : res) {
			result.add((FriendshipRequest) obj);
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.FriendshipManagerRemote#fetch(java.lang.String)
	 */
	public FriendshipRequest fetch(int id) {
		Query q = em.createQuery("FROM FriendshipRequest fr WHERE fr.id=:id");
		q.setParameter("id", id);
		FriendshipRequest fr = (FriendshipRequest) q.getSingleResult();
		return fr;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.FriendshipManagerRemote#accept(entities.FriendshipRequest)
	 */
	@Override
	public void accept(FriendshipRequest fr) {
		fr.accept();
		em.merge(fr);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.FriendshipManagerRemote#refuse(entities.FriendshipRequest)
	 */
	@Override
	public void refuse(FriendshipRequest fr) {
		fr.refuse();
		em.merge(fr);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see sessions.FriendshipManagerRemote#fetchFriends(entities.User)
	 */
	@Override
	public List<User> fetchFriends(String username) {
		List<User> result = new LinkedList<User>();
		Status status = Status.ACCEPTED;
		Query q1 = em
				.createQuery("SELECT fr.toUser FROM FriendshipRequest fr WHERE fr.status=:status AND fr.fromUser.username=:username");
		q1.setParameter("username", username);
		q1.setParameter("status", status);
		Query q2 = em
				.createQuery("SELECT fr.fromUser FROM FriendshipRequest fr WHERE fr.status=:status AND fr.toUser.username=:username");
		q2.setParameter("username", username);
		q2.setParameter("status", status);
		List<?> res1 = q1.getResultList();
		List<?> res2 = q2.getResultList();
		for (Object obj : res1) {
			result.add((User) obj);
		}
		for (Object obj : res2) {
			result.add((User) obj);
		}
		return result;
	}

}
